<template>
  <div class="monitor-box">
    <div class="left-box">
      <div class="control-box">
        <div class="search-box box-shadow">
          <a-form>
            <a-form-item label="所属标段">
              <a-select placeholder="全部" v-model:value="waterFormState.sectionId">
                <a-select-option :value="null" key="0">全部</a-select-option>
                <a-select-option v-for="section in sections" :key="section.sectionId" :value="section.sectionId">
                  {{ section.sectionName }}
                </a-select-option>
              </a-select>
            </a-form-item>
            <a-form-item label="搜索条件">
              <a-input v-model:value="waterFormState.deviceSearch" placeholder="请输入车辆名称或车牌号"></a-input>
            </a-form-item>
            <a-form-item label="仅显示当日在线">
              <a-switch
                  :defaultChecked="waterFormState.workToday==1"
                  @change="()=>{waterFormState.workToday=waterFormState.workToday==1?undefined:1}"/>
              <span style="margin-left: 80px">显示实时位置：</span>
              <a-switch v-model:checked="checked"
                        @change="findDevicePath"/>
            </a-form-item>
            <a-form-item>
              <a-button @click="getDeviceList" type="primary">查询</a-button>
            </a-form-item>
          </a-form>
        </div>
      </div>
      <div class="cell-table-box box-shadow">
        <div class="table-box-header">
          车辆列表
        </div>
        <div class="table-box-center">
          <a-table
              :scroll="{y:setHeight('.table-box-center', 125) + 'px'}"
              :data-source="waterList.deviceInfo"
              :rowKey="(record) => record.deviceId"
              @change="getWaterList"
              :pagination="{
                'total':waterList.totalCount,
                'pageSize':waterList.everyPage,
                'showLessItems':true
              }">
            <a-table-column title="归属标段" data-index="sectionName"></a-table-column>
            <a-table-column title="车辆名称" data-index="deviceName"></a-table-column>
            <a-table-column title="轨迹回放" data-index="deviceId">
              <template #default="{text,record}">
                <div class="table-icon-box">
                  <div @click="openPlaybackModal(text)">
                    <HistoryOutlined/>
                  </div>
                </div>
              </template>
            </a-table-column>
            <a-table-column title="定位" data-index="deviceId" width="50px">
              <template #default="{text,record}">
                <div class="table-icon-box">
                  <div @click="handleCell(text)">
                    <EditOutlined/>
                  </div>
                </div>
              </template>
            </a-table-column>
          </a-table>
        </div>
      </div>
    </div>
    <div class="right-box">
      <div class="base-info-box box-shadow">
        <a-descriptions :column="4">
          <a-descriptions-item label="归属标段" :span="1">
            {{ waterInfo ? waterInfo.sectionName : '--' }}
          </a-descriptions-item>
          <a-descriptions-item label="车辆名称" :span="1">
            {{ waterInfo ? waterInfo.deviceName : '--' }}
          </a-descriptions-item>
          <a-descriptions-item label="设备编号" :span="1">
            {{ waterInfo ? waterInfo.sn : '--' }}
          </a-descriptions-item>
          <a-descriptions-item label="今日里程" :span="1">
            {{ waterInfo ? waterInfo.buildToday : '--' }}
          </a-descriptions-item>
          <a-descriptions-item label="平台里程" :span="1">
            {{ waterInfo ? waterInfo.buildTotle : '--' }}
          </a-descriptions-item>
          <a-descriptions-item label="洒水方量" :span="1">
            {{ waterInfo ? waterInfo.waterTotle : '--' }}
          </a-descriptions-item>
          <a-descriptions-item label="今日方量" :span="1">
            {{ waterInfo ? waterInfo.waterToday : '--' }}
          </a-descriptions-item>
        </a-descriptions>
      </div>
      <div class="map-box box-shadow">
        <div id="mapbox-content"></div>
      </div>
    </div>
  </div>
  <SModal
      title="轨迹回放"
      width="906"
      height="644"
      :isShow="playbackInfo.showPbModal"
      @closed="()=>{showPbModal = false}"
      forceRender="true">
    <div class="pb-track-modal">
      <div class="pb-header-box">
        <span style="font-size: 14px;">起止时间：</span>
        <a-range-picker
            v-model:value="value1"
            :ranges="ranges"
            :show-time="{ defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('11:59:59', 'HH:mm:ss')] }"/>
        <a-button type="primary" @click="getPathByTime" style="margin-left: 40px">查询</a-button>
        <a-button type="primary" @click="getAllPath" style="margin-left: 20px">查询全部</a-button>
      </div>
      <div class="pb-track-box ">
        <div id="trackpb-box"></div>
        <div class="map-event-control">
          <div @click="startClick" :class="{'map-control-button':true}">开始</div>
          <div @click="pauseClick" :class="{'map-control-button':true}">启停</div>
          <div @click="stopClick" :class="{'map-control-button':true}">停止</div>
        </div>
      </div>
    </div>
  </SModal>
</template>

<script lang="ts">
import {useStore} from "vuex"
import {defineComponent, reactive, ref, toRefs, onMounted, onBeforeUnmount, watch, computed, nextTick} from "vue"
import {setHeight} from "@/utils/tableUtils"
import {waterDevice} from "@/hooks/device/index";
import kindDict from "@/dicts/kindDict"
import vehicleTypeDict from "@/dicts/vehicleTypeDict"
import mapboxgl, {AnyLayer, LngLat, Marker, Sources} from "mapbox-gl"
import {EditOutlined, SaveOutlined, DeleteOutlined, CloseOutlined, HistoryOutlined} from '@ant-design/icons-vue'
import {message} from "ant-design-vue"
import axios from "axios"
import redLine from "@/assets/data/redLine.ts"
import "mapbox-gl/dist/mapbox-gl.css"
import {MqttOptions, MqttService} from "@/utils/mqttService"
import config from "@/config/index"
import SModal from "@/components/SModal/index.vue"
import deviceTypeDict from "@/dicts/deviceTypeDict"
import moment, {Moment} from 'moment';
import * as turf from '@turf/turf'
import Track from "@/assets/image/Track.png"

interface MapDeviceInfo {
  deviceId: number
  deviceInfo: any
  deviceMarker: Marker
}

export default defineComponent({
  setup() {
    const store = useStore()
    const userName = ref(JSON.parse(JSON.stringify(store.getters["userinfo/getUserInfo"])).username)
    const sections = ref(JSON.parse(JSON.stringify(store.getters["userinfo/getUserSection"])))
    const {
      waterFormState, waterInfo, waterList, getWaterInfo, getWaterList, getDeviceLocationAndBuild
    } = waterDevice()
    const value1 = ref<Moment[]>([moment('00:00:00', 'HH:mm:ss'), moment('11:59:59', 'HH:mm:ss')])
    const trackId = ref()
    const checked = ref<boolean>(false);
    const centerList = ref()

    let realRouteGeoJson: any = {
      type: 'FeatureCollection',
      features: [{
        type: 'Feature',
        geometry: {
          type: 'LineString',
          coordinates: []
        }
      }]
    }

    let animatePointGeoJson: any = {
      type: 'FeatureCollection',
      features: [{
        type: 'Feature',
        properties: {},
        geometry: {
          type: 'Point',
          coordinates: []
        }
      }]
    }

    const workListInfo = ref({
      showModal: false,
      workList: new Array<any>()
    })

    const playbackInfo = reactive({
      uploadFileRecord: <any>null,
      showPbModal: false,
      playbackList: new Array<any>(),
      active: false
    })

    const realMapInfo = reactive({
      deviceList: new Array<MapDeviceInfo>(),  // 设备信息列表(主要用于marker)
      realSourceName: 'real_cfg',
      realSource: { // 实时施工数据源列表
        type: "FeatureCollection",
        features: new Array<any>(),
      },
      realLayerName: 'real_track', // 实时施工图层列表
      subscribeList: new Array<string>() // 订阅设备列表
    })

    const playbackMapInfo = reactive({
      realSource: { // 实时施工数据源列表
        type: "FeatureCollection",
        features: new Array<any>(),
      },
      realLayerName: 'real_track', //
    })

    let maps: any;
    let trackmap: any;

    // 初始化地图
    const initMap = () => {
      mapboxgl.accessToken = config.map.accessToken
      let mapSource: Sources = {
        google: {
          type: "raster",
          tiles: [
            config.map.baseLayer1URL,
          ],
          tileSize: 256,
        },
      }
      let layers: AnyLayer[] = [
        {
          id: "google-tiles1",
          type: "raster",
          source: "google",
        },
      ]
      maps = {
        map: new mapboxgl.Map({
          container: "mapbox-content",
          style: {
            version: 8,
            sources: mapSource,
            layers: layers,
          },
          minZoom: 5,
          maxZoom: 20,
          center: config.map.center,
          zoom: config.map.zoom,
          attributionControl: false
        }),
        sourceList: new Set<string>(),
        LayerList: new Set<string>()
      }
      maps.map.on("load", () => {
        maps.map.addLayer({
          id: "satellite1",
          type: "raster",
          source: {
            type: "raster",
            tiles: [config.map.baseLayer2URL],
          },
        })
        maps.map.addLayer({
          id: "air",
          type: "raster",
          source: {
            type: "raster",
            tiles: [config.map.airUrl],
          },
        })
        maps.map.addSource("redLineSource", {type: "geojson", data: redLine})
        maps.map.addLayer({
          id: "redLineLayer",
          type: "line",
          source: "redLineSource",
          layout: {},
          paint: {
            "line-color": "#ff0000",
            "line-width": 2,
            "line-opacity": 1
          },
        })
      })

    }
    // 移动地图视角
    const mapToCell = (cellCenter: LngLat) => {
      if (!maps.map) return
      maps.map.jumpTo({center: cellCenter})
    }
    // 移动回放地图视角
    const mapToTrack = (Center: LngLat) => {
      if (!trackmap.map) return
      trackmap.map.jumpTo({center: Center})
    }
    // 列表查询某一辆车
    const handleCell = (deviceId: any) => {
      let f1 = getDeviceLocationAndBuild(deviceId)

      Promise.all([f1]).then((res: any) => {
        // 2.实时数据
        // 先清除旧的实时显示相关的数据,图层,marker
        realMapInfo.deviceList.forEach((item: any) => {
          item.deviceMarker.remove()
        })
        realMapInfo.deviceList = new Array<MapDeviceInfo>()
        MqttService.unsubscribe(realMapInfo.subscribeList)
        realMapInfo.subscribeList = new Array<string>()
        realMapInfo.realSource.features = new Array<any>()

        // 订阅新选定仓面的设备数据
        // workListInfo.value.workList = res[0].data

        let el = document.createElement("div")
        el.className = "device-water"
        el.innerText = `${res[0].data.deviceName}`

        realMapInfo.deviceList.push({
          deviceId: res[0].data.deviceId,
          deviceInfo: res[0].data,
          deviceMarker: new mapboxgl.Marker(el).setLngLat([0, 0]).setOffset(new mapboxgl.Point(86, -16)).addTo(maps.map)
        })
        MqttService.subscribe(`${config.craft.water.mqtt.topic}${res[0].data.sn}`)

        // 跳转位置
        if (res[0].data.latitude && res[0].data.longitude) {
          maps.map.setZoom(17)
          let cellCenter = new mapboxgl.LngLat(res[0].data.longitude, res[0].data.latitude);
          mapToCell(cellCenter)
          realMapInfo.deviceList[0].deviceMarker.setLngLat([res[0].data.longitude, res[0].data.latitude])
        }
      })
    }
    // 初始化回放的地图
    const initMap2 = () => {
      trackmap = {
        map: new mapboxgl.Map({
          container: "trackpb-box",
          style: {
            version: 8,
            sources: {
              google: {
                type: "raster",
                tiles: ['https://webst04.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}'],
                tileSize: 256,
              },
            },
            layers: [
              {
                id: "google-tiles1",
                type: "raster",
                source: "google",
              },
            ],
          },
          minZoom: 5,
          maxZoom: 24,
          center: config.map.center,
          zoom: config.map.zoom,
          attributionControl: false
        }),
        sourceList: new Set<string>(),
        LayerList: new Set<string>()
      }
      trackmap.map.on("load", () => {

        trackmap.map.addLayer({
          id: "satellite1",
          type: "raster",
          source: {
            type: "raster",
            tiles: [config.map.baseLayer2URL],
          },
        })
        trackmap.map.addLayer({
          id: "air",
          type: "raster",
          source: {
            type: "raster",
            tiles: [config.map.airUrl],
          },
        })

        trackmap.map.addSource("redLineSource", {type: "geojson", data: redLine})
        trackmap.map.addLayer({
          id: "redLineLayer",
          type: "line",
          source: "redLineSource",
          layout: {},
          paint: {
            "line-color": "#ff0000",
            "line-width": 2,
            "line-opacity": 1
          },
        })
      })
    }
    // 打开轨迹回放弹框
    const openPlaybackModal = (deviceId: number) => {
      playbackInfo.showPbModal = true
      trackId.value = deviceId
      playbackInfo.active = !playbackInfo.active
      nextTick(function () {
            initMap2()
          }
      )
      if (trackmap.map.getLayer('animatePointLayer', 'realRouteLayer', 'routeLayer'))
        trackmap.map.removeLayer('animatePointLayer', 'realRouteLayer', 'routeLayer')
      if (trackmap.map.getSource('routeLayer', 'animatePointLayer'))
        trackmap.map.removeSource('routeLayer', 'animatePointLayer')
    }
    //查询全部回放
    const getAllPath = () => {
      axios.post("/water/findDeviceHistory", {deviceId: trackId.value}).then((res: any) => {
        if (res.success) {
          if (res.data.realData == null) {
            message.info("当前时间段暂无数据")
          } else {
            let msg: any = []
            centerList.value = res.data.realData[0]
            res.data.realData.map(function (item: any) {
              msg.push([item.longitude, item.latitude])
            })
            playbackMapInfo.realSource.features.push({
              "type": "Feature",
              "geometry": {
                "type": "LineString",
                "coordinates": msg
              }
            })
            addRoutelayer() // 添加轨迹线图层
            // 跳转位置
            if (centerList.value) {
              trackmap.map.setZoom(17)
              let Center = new mapboxgl.LngLat(centerList.value.longitude, centerList.value.latitude);
              mapToTrack(Center)
            }
          }
        } else {
          message.info("暂无数据")
        }
      })
    }
    //查询某一时间段
    const getPathByTime = () => {
      axios.post("/water/findDeviceHistory",
          {
            deviceId: trackId.value,
            startTime: moment((value1.value[0]).toDate()).format('yyyy-MM-DD HH:mm:ss'),
            endTime: moment((value1.value[1]).toDate()).format('yyyy-MM-DD HH:mm:ss'),
          }).then((res: any) => {
        if (res.success) {

          if (res.data.realData == null) {
            message.info("当前时间段暂无数据")
          } else {
            let msg: any = []
            playbackMapInfo.realSource.features = new Array<any>()
            if (trackmap.map.getLayer('realRouteLayer')) trackmap.map.removeLayer('realRouteLayer')
            if (trackmap.map.getSource('realRouteLayer')) trackmap.map.removeSource('realRouteLayer')
            if (trackmap.map.getLayer('routeLayer')) trackmap.map.removeLayer('routeLayer')
            if (trackmap.map.getSource('routeLayer')) trackmap.map.removeSource('routeLayer')

            centerList.value = res.data.realData[0]
            res.data.realData.map(function (item: any) {
              msg.push([item.longitude, item.latitude])
            })

            playbackMapInfo.realSource.features.push({
              "type": "Feature",
              "geometry": {
                "type": "LineString",
                "coordinates": msg
              }
            })
            addRoutelayer() // 添加轨迹线图层
            // 跳转位置
            if (centerList.value) {
              trackmap.map.setZoom(17)
              let Center = new mapboxgl.LngLat(centerList.value.longitude, centerList.value.latitude);
              mapToTrack(Center)
            }
          }
        } else {
          message.info("暂无数据")
        }
      })
    }
    // 实时显示位置
    const findDevicePath = () => {
      realMapInfo.deviceList.forEach((item: any) => {
        item.deviceMarker.remove()
      })
      realMapInfo.deviceList = new Array<MapDeviceInfo>()

      let f1 = getWaterList()
      Promise.all([f1]).then((res: any) => {
        for (let i = 0; i < res[0].data.deviceInfo.length; i++) {
          let el = document.createElement("div")
          el.className = "device-water"
          el.innerText = `${res[0].data.deviceInfo[i].deviceName}`

          realMapInfo.deviceList.push({
            deviceId: res[0].data.deviceInfo[i].deviceId,
            deviceInfo: res[0].data.deviceInfo[i],
            deviceMarker: new mapboxgl.Marker(el).setLngLat([0, 0]).setOffset(new mapboxgl.Point(86, -16)).addTo(maps.map)
          })
        }
        if (checked.value == true) {
          if (waterFormState.value.sectionId == null) {
            MqttService.subscribe(`${config.craft.water.mqtt.topic}#`)
          } else if (waterFormState.value.sectionId != null) {
            MqttService.subscribe(`${config.craft.water.mqtt.topic}${res[0].data.deviceId}`)
          }
        } else {
          realMapInfo.deviceList.forEach((item: any) => {
            item.deviceMarker.remove()
          })
          realMapInfo.deviceList = new Array<MapDeviceInfo>()
        }
      })
    }

    let isPlay = false
    let counter = 0
    let steps = 0
    let aLength = 0;

    let newRouteGeoJson: any;
    // 获取轨迹数据
    const setRouteData = () => {
      if (trackmap.map.getLayer('animatePointLayer')) trackmap.map.removeLayer('animatePointLayer')
      if (trackmap.map.getSource('animatePointLayer')) trackmap.map.removeSource('animatePointLayer')

      animatePointGeoJson.features[0].geometry.coordinates = playbackMapInfo.realSource.features[0].geometry.coordinates[0]
      aLength = playbackMapInfo.realSource.features[0].geometry.coordinates.length;
      newRouteGeoJson = resetRoute(playbackMapInfo.realSource.features[0], 1000, {units: 'kilometers'})
      steps = newRouteGeoJson.geometry.coordinates.length

      trackmap.map.loadImage(require('@/assets/image/Track.png'), function (error: any, Track: any) {
        if (Track) {
          trackmap.map.addImage('Track', Track);
        }
      })
      addRealRouteSource() // 添加实时轨迹线图层
      addAnimatePointSource() // 添加动态点图层
    }

    // 添加轨迹线图层
    const addRoutelayer = () => {
      trackmap.map.addLayer({
        id: 'routeLayer',
        type: 'line',
        source: {
          type: 'geojson',
          lineMetrics: true,
          data: playbackMapInfo.realSource
        },
        paint: {
          "line-width": 6,
          "line-opacity": 1,
          "line-color": '#D0D0D0',
        }
      });
    }

    // 添加实时轨迹线
    const addRealRouteSource = () => {
      trackmap.map.addLayer({
        id: "realRouteLayer",
        type: "line",
        source: {
          type: "geojson",
          lineMetrics: true,
          data: realRouteGeoJson
        },
        paint: {
          "line-width": 6,
          "line-opacity": 1,
          "line-color": '#FF0000',
        }
      });
    }

    // 添加动态点图层
    const addAnimatePointSource = () => {
      trackmap.map.addLayer({
        id: 'animatePointLayer',
        type: 'symbol',
        source: {
          type: 'geojson',
          data: animatePointGeoJson
        },
        layout: {
          "icon-image": 'Track',
          "icon-size": 0.5,
          "icon-rotate": ['get', 'bearing'],
          "icon-rotation-alignment": 'map',
          "icon-allow-overlap": true,
          "icon-ignore-placement": true
        }
      });
      animate()
    }

    const animate = () => {
      if (counter >= steps) {
        return
      }
      let startPnt, endPnt
      if (counter == 0) {
        realRouteGeoJson.features[0].geometry.coordinates = []
        startPnt = newRouteGeoJson.geometry.coordinates[counter]
        endPnt = newRouteGeoJson.geometry.coordinates[counter + 1]
      } else if (counter !== 0) {
        startPnt = newRouteGeoJson.geometry.coordinates[counter - 1]
        endPnt = newRouteGeoJson.geometry.coordinates[counter]
      }

      animatePointGeoJson.features[0].properties.bearing = turf.bearing(
          turf.point(startPnt),
          turf.point(endPnt)
      ) - 90;
      animatePointGeoJson.features[0].geometry.coordinates = newRouteGeoJson.geometry.coordinates[counter];
      realRouteGeoJson.features[0].geometry.coordinates.push(animatePointGeoJson.features[0].geometry.coordinates)

      trackmap.map.getSource('animatePointLayer').setData(animatePointGeoJson);
      trackmap.map.getSource('realRouteLayer').setData(realRouteGeoJson);
      if (isPlay) {
        requestAnimationFrame(animate)
      }
      counter = counter + 1;
    }

    const resetRoute = (route: any, nstep: any, units: any) => {
      let newroute: any = {
        'type': 'Feature',
        'geometry': {
          'type': 'LineString',
          'coordinates': []
        }
      }
      let lineDistance = turf.lineDistance(route);
      let nDistance = lineDistance / nstep;
      for (let i = 0; i < aLength - 1; i++) {
        let from = turf.point(route.geometry.coordinates[i]);
        let to = turf.point(route.geometry.coordinates[i + 1]);
        let lDistance = turf.distance(from, to, units);
        if (i == 0) {
          newroute.geometry.coordinates.push(route.geometry.coordinates[0])
        }
        if (lDistance > nDistance) {
          let rings = lineMore(from, to, lDistance, nDistance, units)
          newroute.geometry.coordinates = newroute.geometry.coordinates.concat(rings)
        } else {
          newroute.geometry.coordinates.push(route.geometry.coordinates[i + 1])
        }
      }
      return newroute
    }

    const lineMore = (from: any, to: any, distance: any, splitLength: any, units: any) => {

      let step = distance / splitLength
      let leftLength = distance - step * splitLength
      let rings = []
      let route = turf.lineString([from.geometry.coordinates, to.geometry.coordinates])
      for (let i = 1; i <= step; i++) {
        let nlength = i * splitLength
        let pnt = turf.along(route, nlength, units);
        rings.push(pnt.geometry.coordinates)
      }
      if (leftLength > 0) {
        rings.push(to.geometry.coordinates)
      }
      return rings
    }

    const startClick = () => {
      setRouteData()
      console.log('开始')
      if (!isPlay) {
        isPlay = true
        counter = 0
        animate()
      }
    }, pauseClick = () => {
      console.log('暂停')
      isPlay = !isPlay
      animate()
    }, stopClick = () => {
      console.log('停止')
      isPlay = false
      counter = 0
      animate()
    }, fastClick = () => {
      setRouteData()
      console.log('二倍速')
      if (!isPlay) {
        isPlay = true
        animate()
        animate()
      }
    }

    onMounted(() => {
      if (sections.value.length > 0) {
        waterFormState.value.sectionId = null
        getWaterList()
      }
      // 加载地图
      initMap()
      // 初始化mqtt
      MqttService.init(
          `${config.craft.water.mqtt.ip}`,
          new MqttOptions(`${config.craft.water.mqtt.userName}`, `${config.craft.water.mqtt.password}`),
          (topic: any, msg: any) => {
            /**
             * 车辆图层
             * 先判断当前车辆在数据源中的位置
             * 若不存在车辆,则新增
             * 若存在,则修改当前记录
             */
            msg = JSON.parse(msg.toString())
            let deviceListIndex = realMapInfo.deviceList.findIndex((item: any) => {
              return item.deviceInfo.deviceId == msg.deviceId
            })
            if (deviceListIndex < 0) return

            realMapInfo.deviceList[deviceListIndex].deviceMarker.getElement().innerText = `${realMapInfo.deviceList[deviceListIndex].deviceInfo.deviceName},${msg.speed}km/h`
            realMapInfo.deviceList[deviceListIndex].deviceMarker.setLngLat([msg.longitude, msg.latitude])
          }
      )
    })

    watch([waterFormState.value], () => {
      findDevicePath();
    }, {immediate: true})


    onBeforeUnmount(() => {
      // 关闭mqtt
      MqttService.unsubscribe(realMapInfo.subscribeList);
      MqttService.end();
      // 移除地图
      if(maps.map) maps.map.remove();
      // if(trackmap.map.remove) trackmap.map.remove();
    })

    return {
      playbackMapInfo, startClick, pauseClick, stopClick, fastClick,
      sections,
      setHeight,
      kindDict,
      vehicleTypeDict,
      checked, realMapInfo,
      handleCell,

      // clickMapControl,
      findDevicePath,

      workListInfo,
      deviceTypeDict,

      waterFormState,
      waterInfo,
      waterList,

      ...toRefs(playbackInfo),
      playbackInfo,

      openPlaybackModal,
      getAllPath,
      getPathByTime,

      value1, moment,
      ranges: {
        '近七日': [moment().startOf("day").subtract(1, "weeks"), moment()],
        '本月': [moment().startOf('month'), moment()]
      },
    }
  },
  components: {EditOutlined, SaveOutlined, DeleteOutlined, CloseOutlined, SModal, HistoryOutlined}
})
</script>

<style lang="scss" scoped>
.monitor-box {
  display: flex;
  width: 100%;
  height: 100%;
  .left-box {
    display: flex;
    flex-direction: column;
    width: 495px;
    height: 100%;
    .control-box {
      display: flex;
      width: 100%;
      height: 222px;
      .search-box {
        width: 100%;
        height: 100%;
        padding: 12px 30px;
        box-sizing: border-box;
        ::v-deep label {
          color: #666666;
        }
        ::v-deep .ant-form-item {
          display: flex;
          margin-bottom: 10px;
        }
        ::v-deep .ant-form-item-control-wrapper {
          flex: 1;
        }
        ::v-deep .ant-select {
          width: 100%;
        }
      }
      .map-control {
        width: 240px;
        height: 100%;
        margin-left: 20px;
        padding: 10px 17px;
        box-sizing: border-box;
        .map-control-title {
          color: #333333;
          font-weight: bold;
        }
        .map-control-title:nth-of-type(n + 2) {
          display: inline-block;
          margin-top: 16px;
        }
        ::v-deep .ant-checkbox-group {
          .ant-checkbox-wrapper {
            width: 100px;
            margin-right: 0px;
            border: 2px solid #1890FF;
            box-sizing: border-box;
            border-radius: 2px;
            color: #1890FF;
            font-size: 12px;
            margin-top: 8px;
            padding: 2px 2px;
            box-sizing: border-box;
            > span:nth-of-type(n + 1) {
              padding-left: 4px;
              padding-right: 4px;
            }
          }
          .ant-checkbox-wrapper:nth-child(odd) {
            margin-right: 6px;
          }
          .ant-checkbox-inner {
            border: 1px solid #1890FF;
          }
        }
      }
    }
    .cell-table-box {
      display: flex;
      flex-direction: column;
      width: 495px;
      flex: 1;
      margin-top: 20px;
      padding: 0 13px;
      .table-box-header {
        color: #333333;
        font-size: 18px;
        font-weight: bold;
        padding: 18px 0 10px 10px;
      }
      .table-box-center {
        width: 100%;
        flex: 1;
      }
      ::v-deep .table-icon-box {
        display: flex;
        justify-content: space-around;
        > div:hover {
          color: #1677FF;
        }
      }
    }
  }
  .right-box {
    display: flex;
    flex-direction: column;
    flex: 1;
    height: 100%;
    margin-left: 20px;
    .base-info-box {
      width: 100%;
      height: 82px;
      padding: 14px 0 0px;
    }
    .map-box {
      position: relative;
      flex: 1;
      width: 100%;
      height: 100%;
      margin-top: 20px;
      box-sizing: border-box;
      .point-info {
        z-index: 1;
        .point-header {
          display: flex;
          width: 100%;
          height: 34px;
          line-height: 34px;
          padding: 0 16px;
          box-sizing: border-box;
          justify-content: space-between;
          border-bottom: 1px solid #eeeeee;
          > span {
            font-weight: bold;
          }
          ::v-deep .anticon {
            line-height: 34px;
          }
        }
      }
      .point-info {
        display: flex;
        flex-direction: column;
        position: absolute;
        top: 40px;
        right: 5px;
        width: 520px;
        height: 230px;
        background: #FFFFFF;
        box-shadow: 0px 2px 16px 0px rgba(0, 0, 0, 0.08);
        border-radius: 2px;
        box-sizing: border-box;
        .point-content {
          display: flex;
          flex-direction: column;
          justify-content: center;
          align-items: center;
          width: 100%;
          padding: 0 16px;
          .info {
            width: 100%;
            ::v-deep .ant-row {
              width: 100%;
              line-height: 37px;
              .ant-col:nth-child(odd) {
                color: #666666;
                font-weight: bold;
              }
              .ant-col:nth-child(even) {
                color: #666666;
              }
            }
          }
        }
      }
      .map-event-control {
        display: flex;
        position: absolute;
        top: 5px;
        right: 5px;
        height: 30px;
        background-color: #FFFFFF;
        border-radius: 3px;
        z-index: 10;
        overflow: hidden;
        .map-control-button {
          width: 90px;
          height: 30px;
          font-size: 14px;
          line-height: 28px;
          text-align: center;
          border: 1px solid #f0f0f0;
          box-sizing: border-box;
          cursor: pointer;
        }
        .map-control-active {
          color: #1890FF;
        }
        .map-control-disable {
          color: #8d8d8d;
        }
      }
      #mapbox-content {
        display: flex;
        width: 100%;
        height: calc(100% - 6px);
        box-sizing: border-box;
      }
      .tamp-legend {
        position: absolute;
        display: flex;
        flex-direction: column;
        padding: 8px 2.5px;
        width: 84px;
        height: 72px;
        right: 5px;
        bottom: 12px;
        background: #FFFFFF;
        border-radius: 3px;
        box-sizing: border-box;
        z-index: 1;
        > div {
          display: flex;
          width: 100%;
          height: 28px;
          .legend {
            display: flex;
            justify-content: center;
            align-items: center;
            width: 28px;
            height: 28px;
            > div {
              width: 12px;
              height: 12px;
              border-radius: 50%;
            }
          }
          .legend-title {
            color: #666666;
            line-height: 28px;
            text-align: center;
          }
        }
      }
      .ex-area-btn {
        position: absolute;
        left: 5px;
        bottom: 12px;
        width: 32px;
        height: 32px;
        background: url("../../../assets/image/ex_area.png") center no-repeat;
        background-size: 18px;
        background-color: #E6F1FC;
        border: 1px solid #1677FF;
        box-sizing: border-box;
        z-index: 1;
      }
      .work-list-btn {
        position: absolute;
        left: 42px;
        bottom: 12px;
        width: 32px;
        height: 32px;
        background: url("../../../assets/image/work_list.png") center no-repeat;
        background-size: 18px;
        background-color: #E6F1FC;
        border: 1px solid #1677FF;
        box-sizing: border-box;
        z-index: 1;
      }
    }
  }
}
.smodal-box {
  box-sizing: border-box;
}
.smodal-to-cell {
  width: 100%;
  height: 100%;
}
.pb-track-modal {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  .pb-header-box {
    margin-top: 15px;
    height: 50px;
  }
  .pb-track-box {
    position: relative;
    flex: 1;
    width: 100%;
    height: 100%;
    margin-top: 5px;
    box-sizing: border-box;
    .map-event-control {
      display: flex;
      position: absolute;
      top: 5px;
      right: 5px;
      height: 30px;
      background-color: #FFFFFF;
      border-radius: 3px;
      z-index: 10;
      overflow: hidden;
      .map-control-button {
        width: 90px;
        height: 30px;
        font-size: 14px;
        line-height: 28px;
        text-align: center;
        border: 1px solid #f0f0f0;
        box-sizing: border-box;
        cursor: pointer;
      }
      .map-control-active {
        color: #1890FF;
      }
      .map-control-disable {
        color: #8d8d8d;
      }
    }
    #trackpb-box {
      display: flex;
      width: 100%;
      height: calc(100% - 6px);
      box-sizing: border-box;
      .mapboxgl-canvas {
        width: 100%;
        height: 100%;
      }
    }
  }
}
</style>

